﻿using System.Collections.Generic;
using ReporterEngine;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace ReportEngine_TestProject
{
    
    
    /// <summary>
    ///This is a test class for InterpreterTest and is intended
    ///to contain all InterpreterTest Unit Tests
    ///</summary>
    [TestClass()]
    public class InterpreterTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


     

        ///// <summary>
        /////A test for Create
        /////</summary>
        //[TestMethod()]
        //public void CreateTest()
        //{
        //    LexPath path = null; // TODO: Initialize to an appropriate value
        //    Interpreter expected = null; // TODO: Initialize to an appropriate value
        //    Interpreter actual;
        //    actual = Interpreter.Create(path);
        //    Assert.AreEqual(expected, actual);
        //    Assert.Inconclusive("Verify the correctness of this test method.");
        //}

        /// <summary>
        ///A test for Execute
        ///</summary>
        [TestMethod()]
        public void ExecuteTest()
        {
            var model = utils.GetSampleModel();
            sQuery query = sQuery.New(model);
            query.Elements.Add(model.Notebook);

            var list = new List<LexPathTest.TestString>();

            list.Add(new LexPathTest.TestString { Text = ">>(‘Organizations‘)>>[>>name==„Novitech Group“]<<subject>>(‘Organization Model’)>>members()", Expected = 63 });//>>(‘Organization’)

            list.Add(new LexPathTest.TestString { Text = ">> (‘Organizations‘) >> [ >> name == „Novitech Group“] << subject >> ('Navigator Model‘)", Expected = 1 });

            list.Add(new LexPathTest.TestString { Text = ">> ('Activity Usages') >> [ << end, start >> count() == \"4\"]", Expected = 23 });

            list.Add(new LexPathTest.TestString { Text = ">> ('Activity Usages') >> [ << end, start >> count() == \"4\" or complexity == \"low\"]", Expected = 57 });
            list.Add(new LexPathTest.TestString { Text = ">> ('Activity Usages') >> [ viewpointDiversity == \"low\" and complexity == \"low\"]", Expected = 44 });

            list.Add(new LexPathTest.TestString { Text = ">> ('Activity Usages') << end, start >> distinct()", Expected = 189 });
            list.Add(new LexPathTest.TestString { Text = ">> ('Activity Usages') << end, start", Expected = 240 });

            list.Add(new LexPathTest.TestString { Text = ">> (Activities, Activities) >> distinct()", Expected = 88 });
            list.Add(new LexPathTest.TestString { Text = ">> (Activities) >> count()", ExpectedValue = "88", IsValueType = true });
            
            list.Add(new LexPathTest.TestString { Text = ">> ('Use Case Models')", Expected = 15 });
            list.Add(new LexPathTest.TestString { Text = ">> (Activities)", Expected =88 });
            list.Add(new LexPathTest.TestString { Text = ">> ('Use Case Models', Activities)", Expected = 103 });

            foreach (var path in list)
            {
                var actualPath = LexPath.Scan(path.Text);

                Interpreter_Accessor target = new Interpreter_Accessor(); // TODO: Initialize to an appropriate value

                var actual = target.Execute(actualPath, query);

                var definitionObj = actual.GetDefinition();

                Assert.AreEqual(false, target.HasError, "path contains error");

                if(!path.IsValueType)
                    Assert.AreEqual(path.Expected, actual.Elements.Count);
                else
                    Assert.AreEqual(path.ExpectedValue, actual.Value);
            }
        }

        /// <summary>
        ///A test for Execute
        ///</summary>
        [TestMethod()]
        public void ExecutePerformanceTest()
        {
            var model = utils.GetSampleModel();
            sQuery query = sQuery.New(model);

            var list = new List<LexPathTest.TestString>();

            list.Add(new LexPathTest.TestString { Text = ">> ('Activity Usages') >> [ viewpointDiversity == \"low\" and complexity == \"low\"]", Expected = 44 });

            list.Add(new LexPathTest.TestString { Text = ">> (Communications) >> start, end", Expected = 200 });
            list.Add(new LexPathTest.TestString { Text = ">> ('Use Case Models')", Expected = 15 });
            list.Add(new LexPathTest.TestString { Text = ">> (Activities)", Expected = 88 });
            list.Add(new LexPathTest.TestString { Text = ">> ('Use Case Models', Activities)", Expected = 103 });

            var start = DateTime.Now;

            var count = 0;

            while ((DateTime.Now - start).TotalSeconds <= 1)
            {
                foreach (var path in list)
                {
                    var actualPath = LexPath.Scan(path.Text);

                    Interpreter_Accessor target = new Interpreter_Accessor();
                        // TODO: Initialize to an appropriate value

                    var actual = target.Execute(actualPath, query);

                    var definitionObj = actual.GetDefinition();

                    count++;
                }
            }

            Assert.IsTrue(count > 1000 ,"slow engine : " + count);
        }

        ///// <summary>
        /////A test for Validate
        /////</summary>
        //[TestMethod()]
        //public void ValidateTest()
        //{
        //    Interpreter_Accessor target = new Interpreter_Accessor(); // TODO: Initialize to an appropriate value
        //    target.Validate();
        //    Assert.Inconclusive("A method that does not return a value cannot be verified.");
        //}
    }
}
